/* eslint-disable no-unused-vars */
/* eslint-disable no-alert */
/* eslint-disable func-names */
/* eslint-disable no-use-before-define */
import store from '../store/index';

let webSocket = null;
let globalCallback = null;// 定义外部接收数据的回调函数
let setIntervalWesocketPush = null;
let webSocketurl = null;

// 初始化websocket
function initWebSocket(url, Callback) {
  webSocketurl = url;
  globalCallback = Callback;
  if ('WebSocket' in window) {
    webSocket = new WebSocket(url);// 创建socket对象
    console.log(webSocket);
  } else {
    alert('该浏览器不支持websocket!');
  }
  webSocket.globalCallback = Callback;
  // 打开
  webSocket.onopen = function (e) {
    webSocketOpen(e);
  };
  webSocket.onmessage =  (e) => {
    webSocketOnMessage(e);
  };
  // 关闭
  webSocket.onclose = function () {
    webSocketClose();
  };
  // 连接发生错误的回调方法
  webSocket.onerror = function () {
    console.log('WebSocket连接发生错误');
  };
}

// 连接socket建立时触发
function webSocketOpen(e) {
  if (e.type === 'open') {
    const data = {
      type: 'open',
      token: sessionStorage.getItem('token') || '',
      time_id: sessionStorage.getItem('time_id') || '',
    };
    sendSock(data);
  }
  sendPing();
  console.log('WebSocket连接成功');
}

// 客户端接收服务端数据时触发,e为接受的数据对象
function webSocketOnMessage(e) {
  const { data } = e;// 根据自己的需要对接收到的数据进行格式化
  const obj = JSON.parse(data);
  if (webSocket.globalCallback && obj.type) {
    webSocket.globalCallback(data);// 将data传给在外定义的接收数据的函数，至关重要。
  }

  /* 在此函数中还可以继续根据项目需求来写其他东西。 比如我的项目里需要根据接收的数据来判断用户登录是否失效了，此时需要关闭此连接，跳转到登录页去。 */
}

// 发送数据
function webSocketSend(data) {
  // if (data.type === 'open') {
  //   webSocket.send(data);
  // } else {
  webSocket.send(JSON.stringify(data));// 在这里根据自己的需要转换数据格式
  // }
}

// 关闭socket
function webSocketClose() {
  // 因为我建立了多个socket，所以我需要知道我关闭的是哪一个socket，就做了一些判断。
  if (
    webSocket.readyState === 1
    // && webSocket.url === webSocketurl
  ) {
    webSocket.close();// 这句话是关键，之前我忘了写，一直没有真正的关闭socket
    clearInterval(setIntervalWesocketPush);
    console.log('对话连接已关闭');
  }
}
const sendPing = (time = 5000, ping = 'ping') => {
  clearInterval(setIntervalWesocketPush);
  webSocket.send(ping);
  setIntervalWesocketPush = setInterval(() => {
    console.log('心跳');
    webSocket.send(ping);
  }, time);
};

// 在其他需要socket地方调用的函数，用来发送数据及接受数据
function sendSock(agentData, callback) {
  globalCallback = callback;// 此callback为在其他地方调用时定义的接收socket数据的函数，此关重要。
  // 下面的判断主要是考虑到socket连接可能中断或者其他的因素，可以重新发送此条消息。
  switch (webSocket.readyState) {
    // CONNECTING：值为0，表示正在连接。
    case webSocket.CONNECTING:
      setTimeout(() => {
        webSocketSend(agentData, callback);
      }, 1000);
      break;
    // OPEN：值为1，表示连接成功，可以通信了。
    case webSocket.OPEN:
      webSocketSend(agentData);
      break;
    // CLOSING：值为2，表示连接正在关闭。
    case webSocket.CLOSING:
      setTimeout(() => {
        webSocketSend(agentData, callback);
      }, 1000);
      break;
    // CLOSED：值为3，表示连接已经关闭，或者打开连接失败。
    case webSocket.CLOSED:
      // do something
      break;
    default:
      // this never happens
      break;
  }
}

// 将初始化socket函数、发送（接收）数据的函数、关闭连接的函数export出去
export default {
  webSocketOnMessage,
  initWebSocket,
  webSocketClose,
  sendSock,
  webSocketSend,
  store,
};
